博客
关于我
C/C++:多进程使用dlopen、dlsym、dlclose装载动态库
阅读量:208 次
发布时间:2019-02-28

本文共 2248 字,大约阅读时间需要 7 分钟。

动态库在多进程环境下的行为可能会让人产生一些误解。很多人认为,同一动态库被多个进程打开时,实际上是共享同一个实例。这并不完全正确。实际上,每个进程在装载动态库时,会创建属于自己的独立实例。尽管动态库的代码和符号可能被多个进程共享,但每个进程都有自己独特的全局变量和互斥锁。这种行为会导致多个进程在使用相同动态库时,彼此之间无法直接看到对方的动态库实例。

为了验证这一点,我设计了一个简单的测试案例。以下是测试的详细步骤:

  • 创建头文件(count.h)
  • #ifndef _COUNT_H
    #define _COUNT_H
    #include
    int count;
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    int get();
    void inc();
    #endif
    1. 创建源文件(count.c)
    2. #include "count.h"
      int get() {
      return count;
      }
      void inc() {
      pthread_mutex_lock(&mutex);
      count++;
      pthread_mutex_unlock(&mutex);
      }
      1. 创建主程序(main.c)
      2. #include 
        #include
        #include
        #include
        #include
        #define NUM 1000
        #define LIBPATH "/home/test1280/libcount.so"
        void *ThreadRun(void *arg) {
        void *handler = dlopen(LIBPATH, RTLD_LAZY);
        if (handler == NULL) {
        printf("ERROR:%s:dlopen\n", dlerror());
        return;
        }
        void (*inc)() = (void (*)())dlsym(handler, "inc");
        if (inc == NULL) {
        printf("ERROR:%s:dlsym\n", dlerror());
        return;
        }
        int (*get)() = (int (*)())dlsym(handler, "get");
        if (get == NULL) {
        printf("ERROR:%s:dlsym\n", dlerror());
        return;
        }
        int i = 0;
        for (; i < NUM; i++) {
        inc();
        usleep(1000 * 1000);
        printf("INFO:PID(%d):%d\n", getpid(), get());
        }
        dlclose(handler);
        }
        int main() {
        pthread_t tid;
        pthread_create(&tid, NULL, ThreadRun, NULL);
        printf("create Thread OK!!!\n");
        while (1); // 按住控制台,观察输出
        return 0;
        }
        1. 编译和链接
        2. gcc -fPIC -c count.c
          gcc -shared count.o -o libcount.so
          gcc -o main main.c -ldl -lpthread
          1. 执行测试
            • 在终端A中运行主程序:
            ./main
            • 在终端B中立即运行主程序:
            ./main

            观察输出结果:

            • 终端A输出:
              create Thread OK!!! INFO:PID(5645):1 INFO:PID(5645):2 INFO:PID(5645):3 ...
            • 终端B输出:
              create Thread OK!!! INFO:PID(5689):1 INFO:PID(5689):2 INFO:PID(5689):3 ...

            从输出结果可以看出,两个进程各自独立地创建了自己的动态库实例,计数器从头开始,互不影响。这说明每个进程在装载动态库时,实际上是创建了独立的实例,包括各自的全局变量和互斥锁。

            通过这些实验,我得出以下结论:

            • 动态库实例是进程私有的:每个进程在装载动态库时,会创建属于自身的独立实例。虽然动态库文件可能被多个进程共享,但每个进程都有自己独特的实例。
            • 全局变量和互斥锁属于特定进程:同一动态库中的全局变量和互斥锁不会在多个进程之间共享。这意味着不同的进程在使用动态库时,无法直接访问对方的进程中的全局变量。
            • 需要谨慎管理共享资源:在多进程环境中使用动态库时,特别是在共享敏感资源时,需要采取措施确保数据的一致性和互斥性。

            这些了解对于开发和优化多线程或多进程程序尤为重要。通过正确管理动态库的装载和使用,可以避免潜在的竞态条件和数据不一致问题。

    转载地址:http://gtgs.baihongyu.com/

    你可能感兴趣的文章
    No module named 'crispy_forms'等使用pycharm开发
    查看>>
    No module named cv2
    查看>>
    No module named tensorboard.main在安装tensorboardX的时候遇到的问题
    查看>>
    No module named ‘MySQLdb‘错误解决No module named ‘MySQLdb‘错误解决
    查看>>
    No new migrations found. Your system is up-to-date.
    查看>>
    No qualifying bean of type XXX found for dependency XXX.
    查看>>
    No qualifying bean of type ‘com.netflix.discovery.AbstractDiscoveryClientOptionalArgs<?>‘ available
    查看>>
    No resource identifier found for attribute 'srcCompat' in package的解决办法
    查看>>
    no session found for current thread
    查看>>
    No toolchains found in the NDK toolchains folder for ABI with prefix: mips64el-linux-android
    查看>>
    NO.23 ZenTaoPHP目录结构
    查看>>
    no1
    查看>>
    NO32 网络层次及OSI7层模型--TCP三次握手四次断开--子网划分
    查看>>
    NOAA(美国海洋和大气管理局)气象数据获取与POI点数据获取
    查看>>
    NoClassDefFoundError: org/springframework/boot/context/properties/ConfigurationBeanFactoryMetadata
    查看>>
    node exporter完整版
    查看>>
    Node JS: < 一> 初识Node JS
    查看>>
    Node Sass does not yet support your current environment: Windows 64-bit with Unsupported runtime(72)
    查看>>
    Node 裁切图片的方法
    查看>>
    Node+Express连接mysql实现增删改查
    查看>>